package com.macro.mall.ums.service.withdraw.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.macro.mall.commission.entity.UserAccountEntity;
import com.macro.mall.commission.enums.UserBalanceChangeChangeTypeEnum;
import com.macro.mall.commission.service.UserAccountService;
import com.macro.mall.commission.service.UserBalanceChangeService;
import com.macro.mall.commission.service.bo.InsertUserBalanceChangeInput;
import com.macro.mall.common.api.exception.BusinessException;
import com.macro.mall.common.api.util.BigDecimalUtils;
import com.macro.mall.ums.domain.MemberWithdrawLog;
import com.macro.mall.ums.entity.MemberWithdrawLogEntity;
import com.macro.mall.ums.enums.MemberWithdrawLogExportStatusEnum;
import com.macro.mall.ums.enums.MemberWithdrawLogStatusEnum;
import com.macro.mall.ums.enums.MemberWithdrawLogWayEnum;
import com.macro.mall.ums.mapper.MemberWithdrawLogMapper;
import com.macro.mall.ums.service.withdraw.MemberWithdrawLogService;
import com.macro.mall.ums.service.withdraw.bo.InsertMemberWithdrawLogInput;
import com.macro.mall.ums.service.withdraw.bo.PagedQueryMemberWithdrawLogInput;
import com.macro.mall.ums.service.withdraw.bo.UpdateMemberWithdrawLogInput;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 会员提现记录Service
 *
 * @author xuyanjun
 * @date 2019-12-28
 */
@Slf4j(topic = "MemberWithdrawLogServiceImpl")
@Service
public class MemberWithdrawLogServiceImpl extends ServiceImpl<MemberWithdrawLogMapper,MemberWithdrawLogEntity> implements MemberWithdrawLogService {

    @Autowired
    private MemberWithdrawLogMapper memberWithdrawLogMapper;

    @Autowired
    private UserAccountService userAccountService;

    @Autowired
    private UserBalanceChangeService userBalanceChangeService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void withdraw(long userId, int amount, String alipayAccount, String alipayRealname) {
        UserAccountEntity userAccountEntity = userAccountService.getByUserId(userId);
        Assert.isTrue(userAccountEntity.getBalance() >= amount, "余额不足。");

        InsertUserBalanceChangeInput insertUserBalanceChangeInput = new InsertUserBalanceChangeInput();
        insertUserBalanceChangeInput
                .setUserId(userId)
                .setChangeAmount(amount)
                .setChangeTypeEnum(UserBalanceChangeChangeTypeEnum.WITHDRAWAL);

        userBalanceChangeService.insert(insertUserBalanceChangeInput);

        InsertMemberWithdrawLogInput insertMemberWithdrawLogInput = new InsertMemberWithdrawLogInput();
        insertMemberWithdrawLogInput
                .setUserId(userId)
                .setAmount(amount)
                .setWay(MemberWithdrawLogWayEnum.ALIPAY.getValue())
                .setAlipayAccount(alipayAccount)
                .setAlipayRealName(alipayRealname)
                .setStatus(0)
                .setExportStatus(0);

        insert(insertMemberWithdrawLogInput);
    }

    /**
     * 新增会员提现记录
     *
     * @param input input
     * @return 新增id
     */
    @Override
    public long insert(InsertMemberWithdrawLogInput input) {
        MemberWithdrawLogEntity memberWithdrawLogEntity = new MemberWithdrawLogEntity();
        memberWithdrawLogEntity
                .setUserId(input.getUserId())
                .setAmount(input.getAmount())
                .setWay(input.getWay())
                .setOpenId(input.getOpenId())
                .setAlipayAccount(input.getAlipayAccount())
                .setAlipayRealName(input.getAlipayRealName())
                .setStatus(input.getStatus())
                .setWithdrawNo(input.getWithdrawNo())
                .setTranNo(input.getTranNo())
                .setExportStatus(input.getExportStatus())
                .setCompleteTime(input.getCompleteTime())
                .setFailReason(input.getFailReason());

        LocalDateTime now = LocalDateTime.now();

        memberWithdrawLogEntity.setCreateTime(now);
        memberWithdrawLogEntity.setUpdateTime(now);


        memberWithdrawLogMapper.insert(memberWithdrawLogEntity);
        return memberWithdrawLogEntity.getId();
    }

    /**
     * 修改会员提现记录
     *
     * @param input input
     */
    @Override
    public void update(UpdateMemberWithdrawLogInput input) {
        MemberWithdrawLogEntity memberWithdrawLogEntity = memberWithdrawLogMapper.selectById(input.getId());
        if (memberWithdrawLogEntity == null) {
            throw new BusinessException(String.format("未能根据Id:%s找到指定的会员提现记录。", input.getId()));
        }

        memberWithdrawLogEntity = new MemberWithdrawLogEntity();
        memberWithdrawLogEntity
                .setId(input.getId())
                .setUserId(input.getUserId())
                .setAmount(input.getAmount())
                .setWay(input.getWay())
                .setOpenId(input.getOpenId())
                .setAlipayAccount(input.getAlipayAccount())
                .setAlipayRealName(input.getAlipayRealName())
                .setStatus(input.getStatus())
                .setWithdrawNo(input.getWithdrawNo())
                .setTranNo(input.getTranNo())
                .setExportStatus(input.getExportStatus())
                .setCompleteTime(input.getCompleteTime())
                .setFailReason(input.getFailReason());

        LocalDateTime now = LocalDateTime.now();
        memberWithdrawLogEntity.setUpdateTime(now);

        memberWithdrawLogMapper.updateById(memberWithdrawLogEntity);
    }

    /**
     * 删除会员提现记录
     *
     * @param id id
     */
    @Override
    public void delete(long id) {
        memberWithdrawLogMapper.deleteById(id);
    }

    /**
     * 根据Id获取会员提现记录
     *
     * @param id id
     * @return 会员提现记录
     */
    @Override
    public MemberWithdrawLog getById(long id) {
        MemberWithdrawLogEntity memberWithdrawLogEntity = memberWithdrawLogMapper.selectById(id);

        return entityToDomain(memberWithdrawLogEntity);
    }

    /**
     * 根据批量Id获取会员提现记录
     *
     * @param batchIds 批量ids
     * @return 会员提现记录集合
     */
    @Override
    public List<MemberWithdrawLogEntity> listByBatchIds(List<Long> batchIds) {
        if (batchIds == null || batchIds.isEmpty()) {
            return new ArrayList<>();
        }

        List<MemberWithdrawLogEntity> memberWithdrawLogEntities = memberWithdrawLogMapper.selectBatchIds(batchIds);

        return memberWithdrawLogEntities;
    }

    /**
     * 分页查询
     *
     * @param input input
     * @return 分页的会员提现记录
     */
    @Override
    public PageInfo<MemberWithdrawLog> pagedQuery(PagedQueryMemberWithdrawLogInput input) {
        LambdaQueryWrapper<MemberWithdrawLogEntity> queryWrapper = Wrappers.lambdaQuery();

        if (input.getMemberId() != null) {
            queryWrapper.eq(MemberWithdrawLogEntity::getUserId, input.getMemberId());
        }

        queryWrapper.orderByDesc(MemberWithdrawLogEntity::getCreateTime);

        PageHelper.startPage(input.getPageIndex(), input.getPageSize());

        Page<MemberWithdrawLogEntity> page = (Page<MemberWithdrawLogEntity>) memberWithdrawLogMapper.selectList(queryWrapper);
        List<MemberWithdrawLog> memberWithdrawLog = entityToDomain(page);

        PageInfo pageInfo = PageInfo.of(page);
        pageInfo.setList(memberWithdrawLog);

        return pageInfo;
    }


    @Override
    public List<MemberWithdrawLogEntity> listByStatusAndExportStatus(MemberWithdrawLogStatusEnum statusEnum, MemberWithdrawLogExportStatusEnum exportStatusEnum) {
        LambdaQueryWrapper<MemberWithdrawLogEntity> queryWrapper = Wrappers.lambdaQuery();

        queryWrapper.eq(MemberWithdrawLogEntity::getStatus, statusEnum.getValue());
        queryWrapper.eq(MemberWithdrawLogEntity::getExportStatus, exportStatusEnum.getValue());

        List<MemberWithdrawLogEntity> memberWithdrawLogEntities = memberWithdrawLogMapper.selectList(queryWrapper);

        return memberWithdrawLogEntities;
    }

    /**
     * 将实体对象转换成domain对象
     *
     * @param memberWithdrawLogEntity 实体
     * @return memberWithdrawLog
     */
    @Override
    public MemberWithdrawLog entityToDomain(MemberWithdrawLogEntity memberWithdrawLogEntity) {
        if (memberWithdrawLogEntity == null) {
            return null;
        }

        MemberWithdrawLog memberWithdrawLog = new MemberWithdrawLog();

        BeanUtil.copyProperties(memberWithdrawLogEntity, memberWithdrawLog);
        memberWithdrawLog.setAmount(BigDecimalUtils.fromFengToYuan(memberWithdrawLogEntity.getAmount(), 2));
        memberWithdrawLog.setWayDesc(MemberWithdrawLogWayEnum.enumOf(memberWithdrawLogEntity.getWay()).getDescription());
        memberWithdrawLog.setStatusDesc(MemberWithdrawLogStatusEnum.enumOf(memberWithdrawLogEntity.getStatus()).getDescription());
        memberWithdrawLog.setExportStatusDesc(MemberWithdrawLogExportStatusEnum.enumOf(memberWithdrawLogEntity.getExportStatus()).getDescription());

        return memberWithdrawLog;
    }

    /**
     * 将实体对象转换成domain对象
     *
     * @param memberWithdrawLogEntities 实体
     * @return memberWithdrawLog
     */
    @Override
    public List<MemberWithdrawLog> entityToDomain(List<MemberWithdrawLogEntity> memberWithdrawLogEntities) {
        List<MemberWithdrawLog> result = new ArrayList<>();
        if (memberWithdrawLogEntities == null) {
            return result;
        }

        for (MemberWithdrawLogEntity memberWithdrawLogEntity : memberWithdrawLogEntities) {
            MemberWithdrawLog memberWithdrawLog = entityToDomain(memberWithdrawLogEntity);
            result.add(memberWithdrawLog);
        }
        return result;
    }

}
